/**
  ******************************************************************************
  * File   : Templates/at32f4xx_it.c 
  * Version: V1.2.5
  * Date   : 2020-10-16
  * Brief  : Main Interrupt Service Routines.
  *          This file provides template for all exceptions handler and peripherals
  *          interrupt service routine.
  ******************************************************************************
  */ 


/* Includes ------------------------------------------------------------------*/
#include "at32f4xx_it.h"
#include "at32f403a_407_board.h"


extern uint8_t rx_buf[16];
extern uint8_t tx_buf[16];
extern uint32_t tx_index;
extern uint32_t rx_index;


/** @addtogroup AT32F4xx_StdPeriph_Templates
  * @{
  */

/** @addtogroup GPIO_LED_Toggle
  * @{
  */

/**
  * @brief  This function handles NMI exception.
  * @param  None
  * @retval None
  */
void NMI_Handler(void)
{
}


/**
  * @brief  This function handles Memory Manage exception.
  * @param  None
  * @retval None
  */
void MemManage_Handler(void)
{
  /* Go to infinite loop when Memory Manage exception occurs */
  while (1)
  {
  }
}

/**
  * @brief  This function handles Bus Fault exception.
  * @param  None
  * @retval None
  */
void BusFault_Handler(void)
{
  /* Go to infinite loop when Bus Fault exception occurs */
  while (1)
  {
  }
}

/**
  * @brief  This function handles Usage Fault exception.
  * @param  None
  * @retval None
  */
void UsageFault_Handler(void)
{
  /* Go to infinite loop when Usage Fault exception occurs */
  while (1)
  {
  }
}

/**
  * @brief  This function handles SVCall exception.
  * @param  None
  * @retval None
  */
void SVC_Handler(void)
{
}

/**
  * @brief  This function handles Debug Monitor exception.
  * @param  None
  * @retval None
  */
void DebugMon_Handler(void)
{
}
// zhong

// static uint8_t uart1_recv_buffer[256];


// 这边只是实现了中断接收功能
// 发送想实现发什么回复什么
uint8_t rx_num;
// void USART1_IRQHandler(void)
// { 
//   //懂了，所以刚刚进不去数据满的中断就是因为这个没写
//   // USART_RDBF_FLAG通过读DT清空

//   while(usart_flag_get(USART1, USART_RDBF_FLAG)==SET){
//     printf("USART1 is running!\r\n");
//     //这两步可以清空空闲
//     rx_num= usart_data_receive(USART1);
//     if(rx_num=='1'){
//        GPIOD->clr = GPIO_PINS_13;
//        printf("led2 is on!\r\n");
//     }
//     else if(rx_num=='2'){
//        GPIOD->clr = GPIO_PINS_14;
//        printf("led3 is on!\r\n");
//     }
//     else if(rx_num=='3'){
//        GPIOD->clr = GPIO_PINS_15;
//        printf("led4 is on!\r\n");
//     }
//     else if(rx_num=='4'){
//       GPIOD->scr = GPIO_PINS_13;
//       GPIOD->scr = GPIO_PINS_14;
//       GPIOD->scr = GPIO_PINS_15;
//       printf("led is all off!\r\n");
//     }

//   }

// }


// 怎么实现输出字符串？收到啥输出啥 实现了已经
// 串口空闲，串口数据通过DMA搬运到串口缓存
// 硬件检测到没有数据搬运就触发空闲，所以不是接收中断那种一个字节就中断一次，而是整组数据结束后中断。而且还能知道数据长度

// 这边只要DMAL5接收，获得tx_buf，然后串口收、发.实现cpu解放 内存存取


void USART1_IRQHandler(void){
  int dma_length=0;
  int i;
  //检测到空闲
  //输出也不对啊，不是串口
  // printf("usart1 \r\n");
  // for(i=0;i<10;i++){
  //     printf("%d",tx_buf[i++]);
  // }
  //   printf("in \r\n");

   if(usart_flag_get(USART1, USART_IDLEF_FLAG)==SET){
      printf("USART1 DMA IDLEF is running!\r\n");
      //外设搬运到内存rx_buf
      usart_data_receive(USART1); 
      //有点像pv
      dma_channel_enable(DMA1_CHANNEL5, FALSE); //防止数据进入
      dma_length =100-DMA1_CHANNEL5->dtcnt; //数据传输量寄存器
      for(i=0;i<dma_length;i++){
        //传输接收到的
        //循环等待 发送缓存数组不为空就发
        //哪里实现了将输入数据的拆分的？ 是DMA吗 DMA就可以直接将xcom的输入存到tx_buf

        //为什么加一句就实现了,这while也没进.延时作用

        // while (usart_flag_get(USART1, USART_TDBE_FLAG)!=SET)
        // {
        //   printf("in \r\n");
        // }
        // 延时一下,不然数据还没发就到下面的
        delay_ms(3);
        // printf("in2 \r\n");
        // printf("idex:%d    ",i);
        usart_data_transmit(USART1,tx_buf[i]);
      }
      printf("\r\n");
      //重新恢复DMA，重装载不设置一直在中断
      DMA1_CHANNEL5->dtcnt=100;
      DMA1_CHANNEL5->maddr=(uint32_t)tx_buf;
      dma_channel_enable(DMA1_CHANNEL5, TRUE); //开启通道
   }


}


// void USART1_IRQHandler(void)
// { 
// // 一个字节中断一次
//   // int cnt =0;
//   printf("usart1\r\n");
//     if(usart_flag_get(USART1, USART_IDLEF_FLAG)==SET){
//       printf("in %lu\r\n",USART1->dt);
//       //没有满
//       while(usart_flag_get(USART1, USART_RDBF_FLAG)!=SET){
//         rx_buf[rx_index++]= usart_data_receive(USART1); //读一次dt就直接被挂起了，
//         printf("jin \r\n");
//       }
      

//       printf("in free\r\n");
//       // for(;tx_index<=rx_index;){
//       //   usart_data_transmit(USART1,rx_buf[tx_index]);
//       // }
//       // printf("\r\n");
//       // printf("%ld\r\n",tx_index);
//     }
//     printf("%ld\r\n",rx_index);
//     // printf("USART1 is running!\r\n");
//     // rx_buf[rx_index++]= usart_data_receive(USART1);
//     // printf("rx_index:%ld\r\n",rx_index);
//     // printf("message I send:\r\n");   
//     // usart_interrupt_enable(USART1, USART_IDLE_INT, FALSE); 
//     // cnt++;

//     // //没发完就继续打印
//     // for(tx_index=0;tx_index<=cnt;tx_index++){
//     //   usart_data_transmit(USART1,tx_buf[tx_index]);
//     // }
//     // printf("\r\n");
    
// }


void EXINT0_IRQHandler(void){
    //判断中断产生并执行操作
    if(exint_flag_get(EXINT_LINE_0)==1){
      printf("EXINT0 is running!\r\n");
      //按下闪烁，松开正常
      while (gpio_input_data_bit_read(GPIOA,GPIO_PINS_0)==SET)
      {
        flashAllLedInTurn();
      }
      TurnOffLed();
      //清除标记
      exint_flag_clear(EXINT_LINE_0);
    }
  }


// 接收到tx数组的东西，之后就是pc的
// 问题：输出的接收和发送是哪里打印的？？
// 串口调试有问题
void DMA1_Channel4_IRQHandler(void)
{
    printf("\r\n");
  // 判断传输已经完成
  if(dma_flag_get(DMA1_FDT4_FLAG))
  {
    printf("DMA1_Channel4 is running!\r\n");
    GPIOD->clr = GPIO_PINS_14; //拉高
    dma_flag_clear(DMA1_FDT4_FLAG);
    printf("send1 sentance:\r\n");
    dma_channel_enable(DMA1_CHANNEL4, FALSE); 
     printf("send1 sentance:\r\n");
    DMA1_CHANNEL4->dtcnt =COUNTOF(tx_buf)-1; // 接收buf大小
    //这边发送完又开启4，使得无限发送
    //我在这边进行修改，只要发送完tx_buf中的接收，就直接将5中断开起来，重新接收数据
    dma_channel_enable(DMA1_CHANNEL5, TRUE); //这句加上才可以发东西，还不知道printf在哪里，优先于第一句的

    printf("\r\n");
  }
}

// 发送的
// L5就一开始执行一下

//xcom发送字符串
// dma5收入，并产生5中断。并开启4使能
// 实现将刚刚发送的东西收回去
void DMA1_Channel5_IRQHandler(void)
{
    printf("\r\n");
  if(dma_flag_get(DMA1_FDT5_FLAG)) // 获取中断标志位
  {
    printf("DMA1_Channel5 is running!\r\n");
    GPIOD->clr = GPIO_PINS_15; //拉高
    dma_flag_clear(DMA1_FDT5_FLAG);
    dma_channel_enable(DMA1_CHANNEL5, FALSE); //先关闭通道，防止其他数据进来影响结果
    // 重写重载，因为装载寄存器在产生中断时已经自减到0。
    // 这边也是中断产生的原因，所以之前数据的长度不对好像中断不开
    DMA1_CHANNEL5->dtcnt =COUNTOF(tx_buf)-1; 
    dma_channel_enable(DMA1_CHANNEL5, TRUE); //开启DMA传输，将外设收到的发给tx_buf

    // 进行修改，接收结束，直接去发送。所以tx_buf也不需要我们自己去预先设置。
    printf("receive sentance:\r\n");
    dma_channel_enable(DMA1_CHANNEL4, TRUE); // 感觉这是来对应自己写好的tx数组的

    // if(tx_buf[0]!='z'&&tx_buf[1]!='k'){
    //   //这边开启了4的中断
    //     dma_channel_enable(DMA1_CHANNEL4, TRUE); // 感觉这是来对应自己写好的tx数组的
    //     printf("\r\n");
    // } 
  }
}


/**
  * @}
  */

/**
  * @}
  */

